import { Animation, _decorator, CCString, Collider2D, Component, Contact2DType, EventTouch, Input, input, instantiate, IPhysics2DContact, Node, Prefab, Vec3, spriteAssembler, Sprite, LRUCache } from 'cc';
import { RewardType, ShootType } from '../Enum';
import { Reward } from './Reward';
import { Enemy } from './Enemy';
import { GameManager } from './GameManager';
import { LeftUI } from './UI/LeftUI';

const { ccclass, property } = _decorator;

@ccclass('Player')
export class Player extends Component {

    @property
    shootRate: number = 0.5;

    @property(Animation)
    anim: Animation;

    @property(Node)
    bulletParent: Node = null

    @property(Prefab)
    bullet1Prefab: Prefab = null

    @property(Prefab)
    bullet2Prefab: Prefab = null

    @property(Node)
    bullet1Position: Node = null;

    @property(Node)
    bullet2Position: Node = null;

    @property(Node)
    bullet3Position: Node = null;

    @property(CCString)
    animHit: string = "";

    @property(CCString)
    animDown: string = "";

    @property
    lifeCount: number = 3;

    @property(LeftUI)
    liftCountUI: LeftUI = null;

    //无敌时间
    invincibleTime: number = 1;
    invincibleTimer: number = 0;
    isInvincible: boolean = false;
    lastReward: Reward = null;
    canControl: boolean = true;

    twoShootTime: number = 10;
    twoShootTimer: number = 0;

    ShootType: ShootType = ShootType.OneShoot;

    collider: Collider2D = null;
    shootTimer: number = 0;

    protected onLoad(): void {
        input.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.collider = this.getComponent(Collider2D);
        if (this.collider) {
            this.collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
        }
    }

    protected onDestroy(): void {
        input.off(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
        if (this.collider) {
            this.collider.off(Contact2DType.BEGIN_CONTACT)
        }
    }

    start() {
        this.liftCountUI.updateUI(this.lifeCount);
    }

    changeLiftCount(count: number) {
        this.lifeCount += count;
        this.liftCountUI.updateUI(this.lifeCount);
    }

    onBeginContact(selfColloder: Collider2D, otherColloder: Collider2D, contact: IPhysics2DContact | null) {
        const reward = otherColloder.getComponent(Reward)
        if (reward) {
            this.onContactToReward(reward);
        } else if (otherColloder.getComponent(Enemy)) {
            this.onContactToEnemy();
        }
    }

    onContactToReward(reward: Reward) {
        if (reward == this.lastReward) return;
        console.log("reward.rewardType", reward.rewardType)
        switch (reward.rewardType) {
            case RewardType.TwoShoot:
                this.transitionToShoot();
                break;
            case RewardType.Bomb:
                //增加玩家炸弹数量
                console.log("进来了-2")
                GameManager.getInstance().AddBomb()
                break;
        }

        reward.getComponent(Collider2D).enabled = false;
        reward.getComponent(Sprite).enabled = false;
    }

    transitionToShoot() {
        this.ShootType = ShootType.TwoShoot;
        this.scheduleOnce(() => {

        })
    }

    onContactToEnemy() {
        if (this.isInvincible) return;

        this.isInvincible = true;
        this.invincibleTimer = 0;

        this.changeLiftCount(-1);
        if (this.lifeCount > 0) {
            this.anim.play(this.animHit)
        } else {
            this.anim.play(this.animDown);
        }

        if (this.lifeCount <= 0) {
            this.ShootType = ShootType.None;
            if (this.collider) {
                this.collider.enabled = false;
            }
        }
    }

    update(dt: number) {
        switch (this.ShootType) {
            //单发子弹
            case ShootType.OneShoot:
                this.oneShoot(dt);
                break;
            //双发子弹
            case ShootType.TwoShoot:
                this.TwoShoot(dt);
                break;
        }
        if (this.isInvincible) {
            this.invincibleTimer += dt;
            if (this.invincibleTimer > this.invincibleTime) {
                this.isInvincible = false;
            }
        }
    }



    transitionToOneShoot() {
        this.ShootType = ShootType.OneShoot;
    }

    TwoShoot(dt: number) {
        this.twoShootTimer += dt;
        if (this.twoShootTimer > this.twoShootTime) {
            this.transitionToOneShoot();
        }
        this.shootTimer += dt;
        if (this.shootTimer >= this.shootRate) {
            this.shootTimer = 0;
            const bullet1 = instantiate(this.bullet2Prefab);
            const bullet2 = instantiate(this.bullet2Prefab);
            this.bulletParent.addChild(bullet1);
            this.bulletParent.addChild(bullet2);
            bullet1.setWorldPosition(this.bullet2Position.worldPosition);
            bullet2.setWorldPosition(this.bullet3Position.worldPosition);
        }
    }

    oneShoot(dt: number) {
        this.shootTimer += dt;
        if (this.shootTimer >= this.shootRate) {
            this.shootTimer = 0;
            const bullet1 = instantiate(this.bullet1Prefab);
            this.bulletParent.addChild(bullet1);
            bullet1.setWorldPosition(this.bullet1Position.worldPosition);
        }
    }



    onTouchMove(event: EventTouch) {
        const p = this.node.position;
        if (!this.canControl) return;
        if (this.lifeCount < 1) return;

        let targetPosition = new Vec3(p.x + event.getDeltaX(), p.y + event.getDeltaY(), p.z);
        if (targetPosition.x < -230) {
            targetPosition.x = -230;
        }
        if (targetPosition.x > 230) {
            targetPosition.x = 230;
        }
        if (targetPosition.y > 380) {
            targetPosition.y = 380;
        }
        if (targetPosition.y < -380) {
            targetPosition.y = -380;
        }

        this.node.setPosition(targetPosition);
    }

    enableController() {
        if (!this.canControl) {
            this.canControl = true;
        }
    }

    disableControl() {
        if (this.canControl) {
            this.canControl = false;
        }
    }
}


